import commonMixin from '@/mixins/common.js'
import cmStyleMixin from '@/mixins/cmStyle.js'

export default {
  name: 'cm-sticky',
  mixins: [
    commonMixin,
    cmStyleMixin
  ],
  props: {
    // 吸顶高度
    top: {
      default: 0,
      type: [Number, String]
    },
    foreverStick: {
      default: false,
      type: Boolean
    }
  },
  data () {
    return {
      // 外侧占位对象的尺寸
      height: 'auto',
      width: 'auto',
      
      // 吸顶容器的布局模式
      stickyPosition: 'static',
    }
  },
  computed: {
    // 吸顶容器ID
    contentId () {
      return this.id + '-content'
    },
    
    // 外侧占位包裹层样式
    wrapperStyle () {
      return {
        // 吸顶外侧占位容器的尺寸
        height: this.height,
        width: this.width
      }
    },
    
    // 吸顶容器样式
    stickyStyle () {
      const result = {
        position: this.stickyPosition
      }
      if (this.stickyPosition === 'fixed') {
        result.top = this.top + 'px'
        result.width = this.width
        result.height = this.height
      }
      return result
    },
    
    // 吸顶容器类
    stickyClass () {
      if (this.stickyPosition === 'fixed') {
        return 'cm-sticky-fixed'
      }
      return ''
    }
  },
  methods: {
    // 阻止点击与滑动事件穿透
    moveHandler () {},
    clickHandler () {},
    
    // 获取吸顶容器内部元素的尺寸，同步给外侧占位对象
    getSize () {
      // 获取容器高度
      let item = uni.createSelectorQuery().in(this).select('#' + this.contentId)
      item.boundingClientRect((data) => {
        // 获取到内容器的宽高
        this.height = data.height + 'px'
        this.width = data.width + 'px'
      }).exec()
    },
    
    // 监测吸顶事件
    observe () {   
      if (this.foreverStick) {
        this.stickyPosition = 'fixed'
        return
      }
      
      if (this.observer && typeof this.observer.disconnect === 'function') {
        this.observer.disconnect()
      }
      
      // 初始化相交观察
      let observer = this.createIntersectionObserver({
        thresholds: [0.95, 0.98, 1]
      })
      // 设置容器与到达页面的什么位置时开始吸顶
      observer.relativeToViewport({
        top: (-1) * parseInt(this.top)
      })
      // 开始监测吸顶
      // observe第一个参数的选择器，无法选中最外层的view
      observer.observe('#' + this.id, (res) => {
        if (res.intersectionRatio < 1) {
          // 设置吸顶
          this.stickyPosition = 'fixed'
          // 触发吸顶事件
          this.$emit('sticky', true)
        }
        else {
          // 取消吸顶
          this.stickyPosition = 'static'
          // 触发吸顶接触事件
          this.$emit('sticky', false)
        }
      })
      this.observer = observer
    },
    
    // 初始化
    init () {
      // 获取容器高度
      this.getSize()
      // 吸顶监测
      this.observe()
    }
  },
  mounted () {
    this.init()
  },
  beforeDestroy () {
    // 关闭掉检测器
    if (this.observer && typeof this.observer.disconnect === 'function') {
      this.observer.disconnect()
    }
  }
}